この項では、TimesTenデータ・ストアのデータの処理について説明します。
内容は次のとおりです。
この項の主な内容は次のとおりです。
TimesTen Connectionではデフォルトで自動コミットが有効になっています。Connection.setAutoCommit()を使用すると、自動コミットを有効/無効を切り替えることができます。自動コミットが無効になっている(falseに設定されている)場合は、Connection.commit()を使用して、トランザクションを手動でコミットする必要があります。
たとえば、自動コミットをオフに設定するには次のように入力します。
con.setAutoCommit(false); // Report any SQLWarnings on the connection // See "Reporting errors and warnings"
複数回実行するSQL文は、Connection.prepareStatement()メソッドをコールして事前に準備しておく必要があります。
最大のパフォーマンスを得るために、パラメータ化した文を準備します。例2.3に、4つのINSERT文をパラメータ化された1つの文に置き換える方法を示します。
値が異なる同様のINSERT文の実行:
Statement.execute("insert into t1 values (1, 2)"); Statement.execute("insert into t1 values (3, 4)"); Statement.execute("insert into t1 values (5, 6)"); Statement.execute("insert into t1 values (7, 8)");パラメータ化した1つのINSERT文を準備し、各文を実行する前にPreparedStatement.set...()メソッドを使用して行の値を設定する方がより効率的です。
PreparedStatement pIns = con.PreparedStatement("insert into t1 values (?,?)"); con.commit(); pIns.setInt(1, Integer.parseInt(1)); pIns.setInt(2, Integer.parseInt(2)); pIns.executeUpdate(); pIns.setInt(1, Integer.parseInt(3)); pIns.setInt(2, Integer.parseInt(4)); pIns.executeUpdate(); pIns.setInt(1, Integer.parseInt(5)); pIns.setInt(2, Integer.parseInt(6)); pIns.executeUpdate(); pIns.setInt(1, Integer.parseInt(7)); pIns.setInt(2, Integer.parseInt(8)); pIns.executeUpdate(); con.commit(); pIns.close();
TimesTenでは、準備された文がコミットされると、自動的に共有されます。たとえば、データ・ストアへの複数の接続でそれぞれ同じ文が準備される場合、TimesTenでは、準備された最初の文が記憶されているため、2番目以降の準備が迅速に返されます。
この例では、3つの接続に対してパラメータ化された同じINSERT文を3つ準備します。接続con1に対して最初に準備するINSERTは、con2接続およびcon3接続で共有されるため、pIns2およびpIns3の準備操作が高速に行われます。
Connection con1; Connection con2; Connection con3; ..... PreparedStatement pIns1 = con1.prepareStatement ("insert into t1 values (?,?)"); con1.commit(); PreparedStatement pIns2 = con2.prepareStatement ("insert into t1 values (?,?)"); con2.commit(); PreparedStatement pIns3 = con3.prepareStatement ("insert into t1 values (?,?)"); con3.commit();
事前にSQL文を準備することによるパフォーマンス上の利点については、「文の事前準備」を参照してください。
SQLを使用してTimesTenデータ・ストアのデータを管理する方法については、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のTimesTenデータ・ストアのデータの処理に関する章を参照してください。この項では、Connection.createStatement()メソッド、Statement.executeUpdate()メソッドおよびStatement.executeQuery()メソッドを使用して、Javaアプリケーション内でSQL文を実行する方法について説明します。
「SQL文の準備」で説明したとおり事前に文が準備されていない場合は、SQL文の特性および返された結果セットに応じて、Statement.execute()、Statement.executeUpdate()、Statement.executeQuery()などのStatement実行メソッドを使用します。
事前に準備されたSQL文には、PreparedStatement.execute()、PreparedStatement.executeUpdate()、PreparedStatement.executeQuery()などのPreparedStatement実行メソッドを使用します。
execute()メソッドは、結果セットがある場合はTrueを返し(SELECTなど)、結果セットがない場合はFalseを返します(INSERT、UPDATE、DELETEなど)。executeUpdate()メソッドは、影響を受ける行数を返します。たとえば、INSERT文を実行すると、executeUpdate()メソッドは挿入された行数を返します。executeQuery()メソッドは結果セットを返すため、結果セットが必要な場合(SELECTの実行時など)にのみコールする必要があります。
Statement.executeUpdate()メソッドを使用して、xyz.customer表へのINSERTを実行するには、次のように入力します。
Connection con; Statement stmt; . . . . . . try { stmt = con.createStatement(); int numRows = stmt.executeUpdate("insert into xyz.customer values" + "(40, 'West', 'Big Dish', '123 Signal St.');"); } catch (SQLException ex) { ..... }
この例では、Statement.executeQuery()メソッドを使用して、xyz.customer表に対してSELECTを実行し、返されたResultSetを表示します。
Statement stmt; . . . . . . try { ResultSet rs = stmt.executeQuery("select cust_num, region, " + "name, address from xyz.customer;"); System.out.println("Fetching result set..."); while (rs.next()) { System.out.println("\n Customer number: " + rs.getInt(1)); System.out.println(" Region: " + rs.getString(2)); System.out.println(" Name: " + rs.getString(3)); System.out.println(" Address: " + rs.getString(4)); } } catch (SQLException ex) { ex.printStackTrace(); }
この例では、PreparedStatement.executeQuery()メソッドを使用して、準備済のSELECT文を実行し、返されたResultSetを表示します。
PreparedStatement pSel = con.prepareStatement("select cust_num, " + "region, name, address " + "from xyz.customer;"); con.commit(); try { ResultSet rs = pSel.executeQuery(); while (rs.next()) { System.out.println("\n Customer number: " + rs.getInt(1)); System.out.println(" Region: " + rs.getString(2)); System.out.println(" Name: " + rs.getString(3)); System.out.println(" Address: " + rs.getString(4)); } } catch (SQLException ex) { ex.printStackTrace(); }
TimesTenでは、DSN属性SqlQueryTimeoutを設定して、すべての接続に対して問合せのタイムアウト期間を指定できます。DSN仕様にSqlQueryTimeoutを設定すると、その値が、今後のデータ・ストアへのすべての接続のデフォルト値となります。
現行の接続のSqlQueryTimeout値を上書きするには、Statement.setQueryTimeout()メソッドをコールして、データ・ストアでSQL問合せが実行される制限時間(秒)を指定します。TimesTenでは、タイムアウト・トリガーが起動されると、実行中の問合せに対してタイムアウトが指示されます。タイムアウト・メッセージが問合せに達するまでにタイムラグが発生する可能性あるため、問合せが終了するまでの実際の時間は、タイムアウト・メッセージが問合せに達するまでにかかる時間と指定したタイムアウト値を加算した時間になります。
Statement.setQueryTimeout()メソッドは、SQL文がアクティブに実行されている場合にのみ動作します。処理のコミット中またはロールバック中にタイムアウトは発生しません。多数のUPDATE、DELETEまたはINSERTを実行するトランザクションでは、コミットまたはロールバックが完了するまでに時間がかかる場合があります。その間、タイムアウト値は無視されます。
この例では、INSERT文とSELECT文を準備し、INSERTを2回実行します。また、SELECTを実行し、返された結果セットを印刷します。作業例については、level1.javaデモを参照してください。
Connection con; Statement stmt; // Disable auto-commit con.setAutoCommit(false); // Report any SQLWarnings on the connection // See "Reporting errors and warnings" // Prepare a parameterized INSERT and a SELECT Statement PreparedStatement pIns = con.prepareStatement("insert into xyz.customer values (?,?,?,?)"); PreparedStatement pSel = con.prepareStatement ("select cust_num, region, name, " + "address from xyz.customer"); // Prepare is a transaction; must commit to release locks con.commit(); // Data for first INSERT statement pIns.setInt(1, Integer.parseInt(100)); pIns.setString(2, 'N'); pIns.setString(3, 'Fiberifics'); pIns.setString(4,'123 any street'); // Execute the INSERT statement pIns.executeUpdate(); // Data for second INSERT statement pIns.setInt(1, Integer.parseInt(101)); pIns.setString(2, 'N'); pIns.setString(3,'Natural Foods Co.'); pIns.setString(4,'5150 Johnson Rd'); // Execute the INSERT statement pIns.executeUpdate(); // Commit the inserts con.commit(); // Done with INSERTs, so close the prepared statement pIns.close(); // Report any SQLWarnings on the connection reportSQLWarnings(con.getWarnings()); CheckIfStopIsRequested(); // Execute the prepared SELECT statement ResultSet rs = pSel.executeQuery(); System.out.println("Fetching result set..."); while (rs.next()) { System.out.println("\n Customer number: " + rs.getInt(1)); System.out.println(" Region: " + rs.getString(2)); System.out.println(" Name: " + rs.getString(3)); System.out.println(" Address: " + rs.getString(4)); } // Close the result set. rs.close(); // Commit the select - yes selects need to be committed too con.commit(); // Close the select statement - we're done with it pSel.close();
TimesTenデータ・ストアから複数のデータ行をフェッチすると、コミット読取り分離レベルが設定されたデータ・ストアに接続しているアプリケーションのパフォーマンスを向上させることができます。
プリフェッチされる行数を指定するには、次の手順を実行します。
この項では、TimesTenで実装されている接続レベルのプリフェッチについて説明します。
プリフェッチ数を0(ゼロ)に設定すると、TimesTenは、データ・ストアに設定した分離レベルに応じて、デフォルトの値を使用します。シリアライズ可能分離モードでは、デフォルトのプリフェッチの値は128です。コミット読取り分離モードでは、デフォルトは5です。デフォルトのプリフェッチの値はほとんどのアプリケーションに最適な設定です。
プリフェッチの値は、0(ゼロ)から128までの任意の整数に再設定できます。シリアライズ可能分離モードが使用されている場合にプリフェッチ数を再設定すると、コミットされるまでロックが設定されます。このため、フェッチと実行の間で遅延が発生した場合は、ロック期間が長くなります。コミット読取り分離モードでは、フェッチが行われるまで読み取られた行のコピーが保持されるため、領域を使用する複数のコピーが存在する場合があります。
プリフェッチを無効にするには、プリフェッチ数を1に設定します。
TimesTenConnection.getTtPrefetchCount()をコールして、現行のプリフェッチ値を確認します。
この例では、ttIsql prefetchcountコマンドを使用して、接続のプリフェッチ数を6に設定します。
この例では、setTtPrefetchCount()を使用して、プリフェッチ数を10に設定し、getTtPrefetchCount()を使用して、カウント変数のプリフェッチ数を返します。
TimesTenConnection con = (TimesTenConnection) DriverManager.getConnection(url); // set prefech count to 10 for this connection con.setTtPrefetchCount(10); // Return the prefetch count to the 'count' variable. int count = con.getTtPrefetchCount();
StatementオブジェクトおよびPreparedStatementオブジェクトに対してaddBatch()メソッドおよびexecuteBatch()メソッドをコールすると、パフォーマンスを向上させることができます。
Statementオブジェクトの場合、バッチは、通常、一連のINSERT文またはUPDATE文で構成されています。結果セットを返す文は、バッチでは使用できません。addBatch()メソッドをコールすると、バッチにSQL文が追加されます。バッチに関連付けられている一連のSQL文は、executeBatch()メソッドによって実行されます。次に例を示します。
// turn off autocommit conn.setAutoCommit(false); Statement stmt = conn.createStatement(); stmt.addBatch("INSERT INTO employees VALUES (1000, 'Joe Jones')"); stmt.addBatch("INSERT INTO departments VALUES (260, 'Shoe')"); stmt.addBatch("INSERT INTO emp_dept VALUES (1000, 260)"); // submit a batch of update commands for execution int[] updateCounts = stmt.executeBatch(); conn.commit ();PreparedStatementオブジェクトの場合、バッチは準備された一連の文の入力パラメータで構成されています。準備された文のパラメータは、setコールを実行した後、addBatch()コールを実行することでバッチに追加されます。バッチはexecuteBatch()メソッドを介して実行されます。次に例を示します。
// turn off autocommit conn.setAutoCommit(false); PreparedStatement stmt = conn.prepareStatement( "INSERT INTO employees VALUES (?, ?)"); // first set of parameters stmt.setInt(1, 2000); stmt.setString(2, "Kelly Kaufmann"); stmt.addBatch(); // second set of parameters stmt.setInt(1, 3000); stmt.setString(2, "Bill Barnes"); stmt.addBatch(); // submit the batch for execution. Check update counts int[] updateCounts = stmt.executeBatch(); conn.commit ();
問合せ以外に、一部のメソッドおよび組込みプロシージャでもTimesTenデータがResultSetオブジェクトの形式で返されます。この項では、TimesTenからのResultSetオブジェクトの使用について説明します。